﻿namespace Iesi.Collections
{
    using System;
    using System.Collections;

    [Serializable]
    public abstract class Set : ISet, ICollection, IEnumerable, ICloneable
    {
        protected Set()
        {
        }

        public abstract bool Add(object o);
        public abstract bool AddAll(ICollection c);
        public abstract void Clear();
        public virtual object Clone()
        {
            Set set = (Set) Activator.CreateInstance(base.GetType());
            set.AddAll(this);
            return set;
        }

        public abstract bool Contains(object o);
        public abstract bool ContainsAll(ICollection c);
        public abstract void CopyTo(Array array, int index);
        public virtual ISet ExclusiveOr(ISet a)
        {
            ISet set = (ISet) this.Clone();
            foreach (object obj2 in a)
            {
                if (set.Contains(obj2))
                {
                    set.Remove(obj2);
                }
                else
                {
                    set.Add(obj2);
                }
            }
            return set;
        }

        public static ISet ExclusiveOr(ISet a, ISet b)
        {
            if ((a == null) && (b == null))
            {
                return null;
            }
            if (a == null)
            {
                return (ISet) b.Clone();
            }
            if (b == null)
            {
                return (ISet) a.Clone();
            }
            return a.ExclusiveOr(b);
        }

        public abstract IEnumerator GetEnumerator();
        public virtual ISet Intersect(ISet a)
        {
            ISet set = (ISet) this.Clone();
            if (a != null)
            {
                set.RetainAll(a);
                return set;
            }
            set.Clear();
            return set;
        }

        public static ISet Intersect(ISet a, ISet b)
        {
            if ((a == null) && (b == null))
            {
                return null;
            }
            if (a == null)
            {
                return b.Intersect(a);
            }
            return a.Intersect(b);
        }

        public virtual ISet Minus(ISet a)
        {
            ISet set = (ISet) this.Clone();
            if (a != null)
            {
                set.RemoveAll(a);
            }
            return set;
        }

        public static ISet Minus(ISet a, ISet b)
        {
            if (a == null)
            {
                return null;
            }
            return a.Minus(b);
        }

        public static Set operator &(Set a, Set b)
        {
            return (Set) Intersect(a, b);
        }

        public static Set operator |(Set a, Set b)
        {
            return (Set) Union(a, b);
        }

        public static Set operator ^(Set a, Set b)
        {
            return (Set) ExclusiveOr(a, b);
        }

        public static Set operator -(Set a, Set b)
        {
            return (Set) Minus(a, b);
        }

        public abstract bool Remove(object o);
        public abstract bool RemoveAll(ICollection c);
        public abstract bool RetainAll(ICollection c);
        public virtual ISet Union(ISet a)
        {
            ISet set = (ISet) this.Clone();
            if (a != null)
            {
                set.AddAll(a);
            }
            return set;
        }

        public static ISet Union(ISet a, ISet b)
        {
            if ((a == null) && (b == null))
            {
                return null;
            }
            if (a == null)
            {
                return (ISet) b.Clone();
            }
            if (b == null)
            {
                return (ISet) a.Clone();
            }
            return a.Union(b);
        }

        public abstract int Count { get; }

        public abstract bool IsEmpty { get; }

        public abstract bool IsSynchronized { get; }

        public abstract object SyncRoot { get; }
    }
}

